<?php

namespace Frieza\Modules\Position\Controllers;

use App\Admin\Extensions\Tools\UserButton;
use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Biz\model\advertisement\MPosition;
use Biz\service\advertisement\AdAdmin;
use Biz\service\advertisement\AdApi;
use Biz\service\advertisement\AdCacheManagement;
use Biz\service\advertisement\AdConfManagement;
use Biz\service\advertisement\AdPositionManagement;
use Doraemon\model\Position\PositionBaseInfo;
use Doraemon\model\Position\PositionWhiteList;
use Doraemon\service\position\AdmOperationModule;
use Doraemon\service\position\ConstInterface;
use Doraemon\service\position\PositionRoute;
use Doraemon\service\position\UserProfileModule\Area;
use Doraemon\tools\HhzClient;
use Doraemon\tools\Msg2Admin;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

/**
 * Class IndexController
 * @package Frieza\Modules\Position\Controllers
 */
class IndexController extends Controller
{

    /**
     * 资源位模拟匹配
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function clearPositionCache(Request $request)
    {
        $id = $request->input('_key');
        $action = $request->input('action');
        $uid = $request->input('uid');
        $api = $request->input('api');

        try {
            if (!$uid) throw new \Exception('用户id必须');
            if (!$api) throw new \Exception('资源位api必须');
            if (!$id) throw new \Exception('资源位配置id必须');

            \Doraemon\service\position\PositionModule::delApiCount($action, $uid, $api, $id);

            $type = 'success';
            $content = '清除成功';
        } catch (\Exception $e) {
            $type = 'error';
            $content = $e->getMessage();
        }
        $result = [
            'status' => true,
            'then'   => [
                'action' => 'refresh',
                'value'  => true,
            ],
            'toastr' => [
                'type'    => $type,
                'content' => $content,
            ]
        ];

        return response()->json($result);
    }

    /**
     * 资源位模拟匹配
     * @param Request $request
     * @param Content $content
     * @return array
     */
    public function api(Request $request)
    {
        $code = 1;
        try {
            $params = $request->all();
            $method = $params['method'] ?? '';
            $uid = $params['uid'] ?? '';
            $app_version = $params['app_version'] ?? '';
            $pos = $params['pos'] ?? '';
            $key_word = $params['keyword'] ?? '';


            if (!$uid) {
                throw new \Exception('uid必须');
            }
            if (!$method) {
                throw new \Exception('参数有误');
            }
            if ($app_version) {
                HhzClient::setClientVersion($app_version);
            }

            $arguments = [
                $uid,
                $user_profile_extend = $app_version ? [
                    'app_version' => $app_version
                ] : [],
                $stat_sign_extend = [],
                $extend = [
                    'pos' => $pos,
                    'tab' => $pos,
                    'id' => $pos,
                    'key_word' => $key_word,
                ],
            ];
            $response = AdApi::debug($method, -1 ^ AdApi::PROCESS_READ_CACHE, ...$arguments);
            $result = $response['response'] ?? [];
            $error = $response['errors'] ?? [];
            $lost = $response['lost_list'] ?? [];
            $content = [
                '返回结果' => $result,
            ];
            if (!empty($lost)) $content['过滤列表'] = $lost;
            if (!empty($error)) $content['错误信息'] = $error;
            dump($content);
        } catch (\Exception $e) {
            $code = 0;
            $msg = $e->getMessage();
            return compact('code', 'msg');
        }
    }

    public function whitelistDel($id)
    {
        $status = true;
        $message = "删除成功";
        try {

            //清除缓存
            AdmOperationModule::delWhitelist($id);

        } catch (\Exception $e) {
            $status = false;
            $message = "操作失败,信息:" . $e->getMessage();
        }

        return response()->json(compact('status', 'message'));
    }

    /**
     * 资源位白名单
     * @param Request $request
     * @param Content $content
     * @return Content
     */
    public function whitelist(Request $request, Content $content)
    {
        //请求参数处理
        $list_name = $request->input('list_name', '');

        $formatStorageList = AdmOperationModule::getWhitelist($list_name);

        $gridModel = new pGridDataModel($formatStorageList['list'], $formatStorageList['count']);

        $gridMap = Admin::grid($gridModel,
            function (Grid $grid) use ($request) {
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->disablePagination();

                //筛选
                $grid->filter(function (Grid\Filter $filter) {
                    // 去掉默认的id过滤器
                    $filter->disableIdFilter();

                    $filter->column(1 / 2, function (Grid\Filter $filter) {

                        $filter->equal('list_name', '名单名称');
                    });

                    $filter->column(1 / 2, function (Grid\Filter $filter) {


                    });

                    //条件展开
                    $filter->expand();
                });

                $grid->column('id', '配置id')->copyable();
                $grid->column('list_name', '名单名称');
                $grid->column('total', '用户总量');
                $grid->column('uid', '用户id')->display(function () {
                    return '点击查看';
                })->modal('用户id', function () {
                    return "<div style='word-wrap: break-word;word-break: normal;'>{$this->uid}</div>";
                });
                $grid->column('start_show_time', '开始时间');
                $grid->column('end_show_time', '结束时间');

                $grid->actions(function (Grid\Displayers\Actions $actions) {
                    $actions->disableView();
                    $actions->disableEdit();
                });


            });
        $title = "用户分群白名单列表";

        if (isset($msg)) $content->body($msg);

        return $content
            ->header($title)
            ->description(' ')
            ->breadcrumb(['text' => '资源位配置管理', 'url' => route('position.main')], ['text' => $title])
            ->row($gridMap);
    }

    public function whitelistCreate(Request $request, Content $content, $id = 0)
    {
        $info = AdmOperationModule::getWhitelistInfo($id);

        $info = ['base' => $info, 'create' => $id == 0];
        $form = new Form($info);
        $form->hidden('create');
        $form->text('base.list_name', '名单名称')->required();
        $form->textarea('base.uid', '用户id')->required();
        $form->dateTimeRange('base.start_show_time', 'base.end_show_time', '生效时间')->required();
        $form->action($request->getPathInfo());

        $tab = new Tab();
        $tab->add('资源位基础信息', $form);
        $moduleName = '用户分群白名单';
        $header = ($id > 0 ? '编辑' : '添加') . $moduleName;
        return $content->header($header)->description(' ')->breadcrumb(
            ['text' => '资源位配置管理', 'url' => route('position.main')],
            ['text' => '用户分群白名单列表', 'url' => route('position.whitelist')],
            ['text' => $header])->row($tab);
    }

    public function whitelistSave(Request $request, $id = 0)
    {
        $baseInfo = $request->input('base', []);
        $create = $request->input('create', 0);

        try {

            PositionWhiteList::action(function () use ($baseInfo, $create) {

                AdmOperationModule::addWhitelistInfo($baseInfo, $create);

            });

            $success = new MessageBag([
                'title' => ($id > 0 ? '编辑' : '添加') . '成功'
            ]);

            return redirect(route('position.whitelist'))->with(compact('success'));

        } catch (\Exception $e) {

            $error = new MessageBag([
                'title' => '错误信息:' . $e->getMessage()
            ]);

            return back()->withInput()->with(compact('error'));

        }
    }

    public function relSave(Request $request, $id)
    {
        $request = $request->all();
        return Msg2Admin::simpleMethod(function () use ($request, $id) {
            AdPositionManagement::opAuth();
            $name = $request['name'] ?? '';
            $value = $request['value'] ?? '';
            if (isset($request['rel'])) {
                $name = 'rel';
                $value = current($request['rel']);
            }
            if (isset($request['app_tab'])) {
                $name = 'app_tab';
                $value = array_sum($request['app_tab']);
            }
            if (isset($request['style_type'])) {
                $name = 'style_type';
                $value = current($request['style_type']);
            }
            if (isset($request['drop_version'])) {
                $name = 'drop_version';
                $value = array_sum($request['drop_version']);
            }
            if (isset($request['op_roles'])) {
                $name = 'op_roles';
                $value = empty($request['op_roles']) ? '' : implode(',', $request['op_roles']);
            }

            if (isset($request['super_role'])) {
                $name = 'super_role';
                $value = empty($request['super_role']) ? '' : implode(',', $request['super_role']);
            }

            $id = $request['pk'] ?? $id;
            $data = [];
            $conf = AdAdmin::positionList();
            if (!isset($conf[$id])) throw new \Exception('配置缺失');
            switch ($name) {
                case 'sign':
                    $data['sign'] = $value;
                    break;
                case 'rel':
                    $data['rel'] = $value;
                    break;
                case 'alias':
                    $data['alias'] = $value;
                    break;
                case 'en_name':
                    $data['en_name'] = $value;
                    foreach ($conf as $v) {
                        if ($v['en_name'] == $value) throw new \Exception(vsprintf("%s与id[%s]标识一致", [$value,$v['id']]));
                    }
                    break;
                case 'title':
                    $data['title'] = $value;
                    if (mb_strlen($value) <= 0 || mb_strlen($value) > 40) {
                        throw new \Exception('资源位置名称长度1~40' . mb_strlen($value));
                    }
                    break;
                case 'app_tab':
                    $data['app_tab'] = $value;
                    break;
                case 'style_type':
                    $data['style_type'] = $value;
                    break;
                case 'drop_version':
                    $data['drop_version'] = $value;
                    break;
                case 'super_role':
                    $data['super_role'] = $value;
                    break;
                case 'op_roles':
                    $data['op_roles'] = $value;
                    break;
                default:
                    throw new \Exception('未定义的快速更新字段');
            }

            if ($id && $data) {
                $conf[$id] = $data + $conf[$id];
                $new = [];
                foreach ($conf as $k => $v) {
                    unset($v['route']);
                    unset($v['statSign']);
                    unset($v['sort']);
                    unset($v['version']);
                    ksort($v);
                    $new[$k] = $v;
                }
                AdPositionManagement::writeConf($new);
            }
        });
    }

    private function indexGrid($list, $is_all): Grid
    {
        $gridModel = new pGridDataModel($list);
        return Admin::grid($gridModel,
            function (Grid $grid) use ($is_all) {
                $grid->disableExport();
                $grid->disableCreateButton();
                $grid->disableRowSelector();
                $grid->disablePagination();
                $grid->tools(function (Grid\Tools $tool) use ($grid) {
                    $tool->append(new UserButton(UserButton::TYPE_HREF, 'whitelist', '资源位白名单', 'fa-search'));
                });
                //筛选
                $grid->filter(function (Grid\Filter $filter) {
                    // 去掉默认的id过滤器
                    $filter->disableIdFilter();

                    $filter->column(1 / 2, function (Grid\Filter $filter) {
                        $filter->equal('uid', '用户id')->default();
                        $filter->equal('app_version', 'app版本')->placeholder('格式:5.17.0');
                    });

                    $filter->column(1 / 2, function (Grid\Filter $filter) {
                        $filter->equal('pos', '位置/tab/id')->default();
                        $filter->equal('keyword', '关键词')->default();
                    });
                });
                $multipleSelectLen = 120;
                $op = AdPositionManagement::opAuth(false);
                $admin = Admin::user()->isAdministrator();

                $grid->column('title', '资源位名称')->editable();
                $grid->column('count', '数量');
                $grid->column('rel', '占位')->select(MPosition::REL_MAP);

                if ($op) {
                    if ($is_all) {
                        $grid->column('id')->width(80);
                    } else {
                        $grid->column('id')->width(80)->sort();
                    }

                    $grid->column('en_name', '标识')->editable();
                    $grid->column('style_type', '类型')->select(['' => '-', 'single_banner' => '单图', 'single_float_banner' => '悬浮图', 'carousel_banner' => '轮播图', 'carousel_banner_with_pos' => '带位置的轮播图', 'broadcast_with_pos' => '带位置的广播', 'card_with_pos' => '带位置的卡片']);
                    $grid->column('alias', '别名');
                    $grid->column('app_tab', '位置')->using(['0' => '-'] + ConstInterface::APP_TAB_MAP);
                    $grid->column('sign', 'statSign')->editable();
                    $grid->column('drop_version', '功能')->multipleSelect(AdConfManagement::FIELD_MAP)->width($multipleSelectLen);
                    $grid->column('op_roles', '操作角色')->multipleSelect(AdmOperationModule::roles())->width($multipleSelectLen);
                    $grid->column('super_role', '管理员')->multipleSelect(AdmOperationModule::roles())->width($multipleSelectLen);
                }

                if ($admin) {
                    $grid->column('cache', '缓存id')->display(function () {
                        return $this->cache === false ? '无' : ($this->cache ? '点击查看' : '空缓存');
                    })->modal('缓存id', function () {
                        return "<div style='word-wrap: break-word;word-break: normal;'>{$this->cache}</div>";
                    });
                }


                $grid->actions(function (Grid\Displayers\Actions $actions) use ($admin) {
                    $actions->disableEdit();
                    $actions->disableDelete();
                    if ($admin) $actions->prepend('<a class="fa fa-remove del-data" data-name="' . $actions->row->title . '" data-position_id="' . $actions->row->id . '" href="javascript:void(0);")>清除缓存</a>');
                    $actions->prepend('<a class="fa fa-bug watch-data" data-name="' . $actions->row->title . '" data-method="' . $actions->row->en_name . '" href="javascript:void(0);")>接口返回</a>');
                    $actions->prepend('<a class="fa fa-info-circle" target="_blank" href="' . $actions->row->uri . '")>查看配置</a>');
                });
            });
    }

    public function main(Request $request, Content $content): Content
    {
        Admin::script($this->positionListScript());
        $app_tab_id = $request->input('tab', ConstInterface::APP_TAB1);
        $tab = new Tab();
        //资源位
        $list = AdAdmin::positionList();

        $ids = array_keys($list);
        list($items, $noCacheKeys) = AdCacheManagement::getAllPositionCache($ids);

        $rs = empty($ids) ? [] : PositionBaseInfo::getActiveCount($ids, $nowDate = date('Y-m-d H:i:s'));
        $activeCount = empty($rs) ? [] : array_column($rs, 'count', 'position_id');

        $tabGroup = [];
        foreach ($list as $v) {
            $id = $v['id'];
            $v['super_role'] = explode(',', $v['super_role']);
            $v['op_roles'] = explode(',', $v['op_roles']);
            $cache = $items[$id] ?? [];
            $v['cache'] = in_array($id, $noCacheKeys) ? false : implode(',', array_column($cache, 'id'));
            $prefix = $v['app_tab'];
            $v['count'] = $activeCount[$id] ?? '-';
            $v['uri'] = PositionRoute::generateRoute($id);
            $v['drop_version'] = AdConfManagement::formatField($v['drop_version']);
            $tabGroup[$prefix][] = $v;
            $tabGroup['_all'][] = $v;
        }

        $positions = $tabGroup[$app_tab_id] ?? [];

        $tabs = ConstInterface::APP_TAB_MAP;
        $tabs['_all'] = '_all';
        foreach ($tabs as $key => $name) {
            $tab->addLink($name . " " . count($tabGroup[$key] ?? []), route('position.main', ['tab' => $key]), $active = $key == $app_tab_id);
        }
        $is_all = $app_tab_id == '_all';
        if ($is_all) {
            $sort = array_column($positions, 'id');
            array_multisort($sort, SORT_DESC, $positions);
        }
        $gridMap = $this->indexGrid($positions, $is_all);

        return $content
            ->header('APP固定资源位')
            ->description(' ')
            ->breadcrumb(['text' => 'APP固定资源位'])
            ->row($tab)
            ->row($gridMap);
    }

    public function sort(Request $request)
    {
        $sortInfo = $request->input('sort');

        AdPositionManagement::sort($sortInfo);
    }

    public function area(Request $request)
    {
        $pid = $request->input('q', 0);
        $areas = Area::getLocation($pid);
        $format = array_map(function ($k, $v) {
            return [
                'id'   => $k,
                'text' => $v,
            ];
        }, array_keys($areas), $areas);
        return response()->json($format);
    }

    public function area4name(Request $request)
    {
        $pid = $request->input('q', 0);
        $areas = Area::getLocation($pid);
        $format = array_map(function ($k, $v) {
            return [
                'id'   => $v,
                'text' => $v,
            ];
        }, array_keys($areas), $areas);
        return response()->json($format);
    }

    private function positionListScript()
    {
        $url = route('position.delPosition');
        $api = route('position.api');
        return <<<EOF
$('.watch-data').on('click', function() {

    var _this = $(this);
    var method = $(this).data('method');
    var uid = $(":input[name='uid']").val();
    var app_version = $(":input[name='app_version']").val();
    var pos = $(":input[name='pos']").val();
    var keyword = $(":input[name='keyword']").val();
    var data = {
        uid:uid,
        app_version:app_version,
        pos:pos,
        keyword:keyword,
        method:method
    };
    $.post('{$api}', data, function(result) {
        if(result.code == 0) {
            toastr.error(result.msg, null, {
                timeOut : 1000
            }); 
        } else {
            layer.open({
                title: '返回结果',
                maxmin: true,
                area: ['800px', '500px'],
                content: result
            });
        }   
    });

});
$('.del-data').on('click', function() {
    var _this = $(this);
    var position_id = $(this).data('position_id');
    var name = $(this).data('name');
    swal({
        title: "确认删除[" + name + "]的缓存吗？",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: "确认",
        showLoaderOnConfirm: true,
        cancelButtonText: "取消",
        preConfirm: function() {
            $.post('{$url}', {position_id:position_id}, function(result) {
                if(result.code == 1) {
                    toastr.success(result.msg, null, {
                        timeOut : 1000
                    });   
                                        $.admin.reload();
        
                } else {
                    toastr.error(result.msg, null, {
                        timeOut : 1000
                    }); 
                                        $.admin.reload();
                }   
            });
        }
    });
    
});
EOF;
    }
}
